package com.yy.micro.magic.data.resource;

import com.yy.micro.magic.data.domain.MagicRuleVo;
import com.yy.micro.magic.data.domain.MagicPlanScheduleVo;
import com.yy.micro.magic.data.entity.MagicRuleEntity;
import com.yy.micro.magic.data.entity.MagicPlanScheduleEntity;
import com.yy.micro.magic.data.repository.MagicRuleRepository;
import com.yy.micro.magic.data.repository.MagicPlanScheduleRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.validation.constraints.NotNull;


@Component
public class PlanSchemeResource {

    @Autowired
    private MagicPlanScheduleRepository repository;

    @Autowired
    private MagicRuleRepository ruleRepository;

    public MagicPlanScheduleVo update(MagicPlanScheduleVo scheme){
        List<MagicRuleVo> rules = scheme.getRules();
        if (null != rules){
            Set<Long> ruleIds = rules.stream().map(r->r.getRuleId()).collect(Collectors.toSet());
            scheme.setRuleList(ruleIds);
            rules.forEach(r->{
                ruleRepository.save(r.to());
            });
        }
        MagicPlanScheduleEntity magicPlanScheduleEntity = repository.save(scheme.to());
        return MagicPlanScheduleVo.create().from(magicPlanScheduleEntity);
    }

    public MagicPlanScheduleVo load(Long schemeId){
        Optional<MagicPlanScheduleEntity> optional = repository.findById(schemeId);
        if (optional.isPresent()){
            MagicPlanScheduleEntity scheme = optional.get();
            loadPlanRules(scheme);
            return MagicPlanScheduleVo.create().from(scheme);
        }
        return null;
    }

    public MagicPlanScheduleVo copyPlanSchedule(@NotNull String srcPlanCode, @NotNull String targetPlanCode){
        MagicPlanScheduleEntity entity = repository.findByPlanCode(srcPlanCode);
        if (null != entity){
            MagicPlanScheduleEntity e = new MagicPlanScheduleEntity();
            e.setPlanCode(targetPlanCode);
            e.setVersion("1.0");
            e.setRuleList(entity.getRuleList());
            entity =repository.save(e);
            loadPlanRules(entity);
            return MagicPlanScheduleVo.create().from(entity);
        }
        return  null;
    }

    public MagicPlanScheduleVo findByPlanCode(String planCode){
        return findByPlanCode(planCode,null);
    }

    public MagicPlanScheduleVo findByPlanCode(String planCode, String version){
        MagicPlanScheduleEntity entity = null;
        if (null != version){
            entity =repository.findByPlanCodeAndVersion(planCode,version);
        }else {
            entity = repository.findByPlanCode(planCode);
        }

        if (null != entity){
            loadPlanRules(entity);
            return  MagicPlanScheduleVo.create().from(entity);
        }
        return null;
    }

    private void loadPlanRules(final MagicPlanScheduleEntity entity) {
        Set<Long> ruleList = entity.getRuleList();
        if (null != ruleList && !ruleList.isEmpty()) {
            List<MagicRuleEntity> rules = new ArrayList<>();
            ruleList.forEach(ruleId -> {
                Optional<MagicRuleEntity> ruleOpt = ruleRepository.findById(ruleId);
                if (ruleOpt.isPresent()) {
                    rules.add(ruleOpt.get());
                }
            });
            entity.setRules(rules);
        }
    }
}
